package com.csci.feishuapp.demo3.utils;

//import org.apache.commons.lang3.StringUtils;

import org.thymeleaf.util.StringUtils;

import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;

/**
 * 日期处理工具类
 * <p>
 *
 * @author : terrytao
 * @date : 10/16/2019
 */
public class DateUtils {

    private static final String DATE_PATTERN = "yyyy-MM-dd";

    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    private static final String SHORT_DATE_PATTERN = "yyyyMMdd";

    /**
     * eg: 2019-12-04T01:19:50.280Z
     */
    public static final String DEFAULT_UTC_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";

    /**
     * eg: 2015-01-17T16:57:33.86
     */
    public static final String DEFAULT_DATE_TIME_SS_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SS";

    /**
     * 默认日期时间格式
     */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 默认日期格式
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    /**
     * 默认时间格式
     */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    /**
     * 将时间对象转化为日期字符串:yyyy-MM-dd
     *
     * @param target
     * @return
     */
    public static String toDateString(TemporalAccessor target) {
        return DateTimeFormatter.ofPattern(DATE_PATTERN).format(target);
    }

    /**
     * 将时间对象转换为日期时间字符串:yyyy-MM-dd HH:mm:ss
     *
     * @param target
     * @return
     */
    public static String toDatetimeString(TemporalAccessor target) {
        return DateTimeFormatter.ofPattern(DATE_TIME_PATTERN).format(target);
    }

    /**
     * 转换为短日期形式：yyyyMMdd
     *
     * @param target
     * @return
     */
    public static String toShortDateString(TemporalAccessor target) {
        return DateTimeFormatter.ofPattern(SHORT_DATE_PATTERN).format(target);
    }

    /**
     * 转换为yyMM
     * @param target
     * @return
     */
    public static String toShortYearMonth(TemporalAccessor target) {
        return DateTimeFormatter.ofPattern("yyMM").format(target);
    }

    /**
     * LocalDateTime转换为Date
     *
     * @param target
     * @return
     */
    public static Date toDate(LocalDateTime target) {
        return Date.from(target.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获得指定日期当天的最早时间
     *
     * @param date
     * @return
     */
    public static LocalDateTime beginOfDate(String date) {
        LocalDate localDate = toLocalDateTime(date).toLocalDate();
        return localDate.atStartOfDay();
    }

    /**
     * 获得指定日期当天的最早时间
     *
     * @param dateTime
     * @return
     */
    public static LocalDateTime beginOfDate(LocalDateTime dateTime) {
        return dateTime.toLocalDate().atStartOfDay();
    }

    /**
     * 获得指定日期当天的最晚时间
     *
     * @param dateTime
     * @return
     */
    public static LocalDateTime endOfDate(LocalDateTime dateTime) {
        return dateTime.toLocalDate().plusDays(1).atStartOfDay().minusNanos(1);
    }

    /**
     * 获得指定日期当天的最晚时间
     *
     * @param date
     * @return
     */
    public static LocalDateTime endOfDate(String date) {
        LocalDate localDate = toLocalDateTime(date).toLocalDate();
        return localDate.plusDays(1).atStartOfDay().minusNanos(1);
    }

    /**
     * 将指定的时间字符串按照规定格式转换为{@link LocalDateTime}
     * 转换失败则返回null
     *
     * @param dateString
     * @param pattern
     * @return
     */
    public static LocalDateTime toLocalDateTime(String dateString, String pattern) {
        try {
            return LocalDateTime.from(DateTimeFormatter.ofPattern(pattern).parse(dateString));
        } catch (Exception e) {
            return null;
        }
    }

    public static LocalDateTime toLocalDateTime(String date) {
        return toLocalDateTime(convertDateFormat(date), DEFAULT_DATE_TIME_FORMAT);
    }

    /**
     * to: yyyy-MM-dd HH:mm:ss
     *
     * @param target
     * @return
     */
    public static String convertDateFormat(String target) {
        StringBuilder sbResult = new StringBuilder(19);
        String trimString = StringUtils.trim(target);
        for (int i = 0, iLength = trimString.length(); i < iLength; i++) {
            char c = trimString.charAt(i);
            if (Character.isDigit(c)) {
                sbResult.append(c);
            }
            if ((i == iLength - 1) || sbResult.length() == 19) {
                break;
            }
            if (sbResult.length() == 4 || sbResult.length() == 7) {
                sbResult.append("-");
            }
            if (sbResult.length() == 10) {
                sbResult.append(" ");
            }
            if (sbResult.length() == 13 || sbResult.length() == 16) {
                sbResult.append(":");
            }
        }
        if (sbResult.length() == 10) {
            sbResult.append(" 00:00:00");
        }
        if (sbResult.length() == 11) {
            sbResult.append("00:00:00");
        }
        if (sbResult.length() == 16) {
            sbResult.append(":00");
        }
        if (sbResult.length() != 19) {
            throw new IllegalArgumentException(MessageFormat.format("不能识别的时间格式: {0}", target));
        }
        return sbResult.toString();
    }

    public static boolean pastIn30Days(LocalDateTime target) {
        return target.isAfter(LocalDateTime.now().minusDays(30)) && target.isBefore(LocalDateTime.now());
    }

    public static boolean pastIn30To60Days(LocalDateTime target) {
        return target.isAfter(LocalDateTime.now().minusDays(60)) && target.isBefore(LocalDateTime.now().minusDays(30));
    }

    public static boolean pastIn60To90Days(LocalDateTime target) {
        return target.isAfter(LocalDateTime.now().minusDays(90)) && target.isBefore(LocalDateTime.now().minusDays(60));
    }

    public static boolean pastIn90To180Days(LocalDateTime target) {
        return target.isAfter(LocalDateTime.now().minusDays(180)) && target.isBefore(LocalDateTime.now().minusDays(90));
    }

    public static boolean pastIn180To270Days(LocalDateTime target) {
        return target.isAfter(LocalDateTime.now().minusDays(270)) && target.isBefore(LocalDateTime.now().minusDays(180));
    }

    public static boolean pastIn270To360Days(LocalDateTime target) {
        return target.isAfter(LocalDateTime.now().minusDays(360)) && target.isBefore(LocalDateTime.now().minusDays(270));
    }

    public static boolean pastOverAYear(LocalDateTime target) {
        return target.isBefore(LocalDateTime.now().minusDays(360));
    }

    public static void main(String[] args) {
        System.out.println(toDateString(LocalDateTime.now()));
        System.out.println(toDatetimeString(LocalDateTime.now()));
        System.out.println(toShortDateString(LocalDateTime.now()));
        System.out.println(toDate(LocalDateTime.now()));
        System.out.println("----");
        System.out.println(beginOfDate("2019-11-12"));
        System.out.println(endOfDate("2019-11-12"));
        System.out.println("----");
        System.out.println(toShortYearMonth(LocalDateTime.now()));

        System.out.println("=============");
        String target = "2019-12-20T17:13:38.977";
        System.out.println(convertDateFormat(target));
        target = "2019-12-20 17:13:38.977";
        System.out.println(convertDateFormat(target));
        target = "2019-12-20";
        System.out.println(convertDateFormat(target));
        target = "2019-12-20 11:11";
        System.out.println(convertDateFormat(target));
        target = "2019-12-20 11:11:22";
        System.out.println(convertDateFormat(target));
        target = "2019/12/20 11:11";
        System.out.println(convertDateFormat(target));
    }
}
